#include<sys/wait.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<iostream>
#include<pthread.h>
#include<signal.h>
using namespace std;

void Service(int new_sock)
{
  while(true)
  {  
  char buf[1024] = {0};
  ssize_t n = read(new_sock,buf,sizeof(buf)-1);
  if(n > 0)
  {
    buf[n] = 0;
    cout <<"client #" << buf << endl;
    //构建响应回去
    std::string echo = ">>>>>server<<<<<";
    echo += buf;
    write(new_sock,echo.c_str(),echo.size());
  }
  else if(n == 0)
  {
    cout << newsock  <<"  client quit...." << endl;
    break;
  }
  else 
  {
    cerr << "read err "<<endl;
    break;
  }
  }
}

void* handle(void* arg)
{
  pthread_detach(pthread_self());//线程分离
  int sock = *(int*)arg;//为哪个套接字提供服务
  delete (int*)arg;//销毁空间，否则会造成内存泄漏！！！
  Service(sock);
  close(sock);//当线程服务完成之后再关闭套接字
}
//服务器不需要绑定固定的ip，只需要绑定INADDR_ANY 让os帮我们绑定一个ip
void Usage(std::string proc)
{
  cout << "Usgae\n\t" << proc <<" port" << endl;
  exit(1);
}
int main(int argc,char* argv[])
{
  if(argc != 2)
  {
    Usage(argv[0]);
  }
  uint16_t port = atoi(argv[1]);
  int listen_sock = socket(AF_INET,SOCK_STREAM,0);
  cout <<"socket success " << endl;
  struct sockaddr_in local;
  memset(&local,0,sizeof(local));
  local.sin_family = AF_INET;
  local.sin_port = htons(port);
  local.sin_addr.s_addr = INADDR_ANY;
  if(bind(listen_sock,(struct sockaddr*)&local,sizeof(local)) < 0)
  {
    cerr <<" bind err " << endl;
  }
  cout << "bind success" << endl;
  if(listen(listen_sock,5) < 0)
  {
    cerr <<"listen err " << endl;
  }
  cout <<"listen success" << endl;
  cout <<"begin service " << endl;
  for(;;)
  {
    struct sockaddr_in peer;
    socklen_t len = sizeof(peer);
    memset(&peer,0,sizeof(peer));

    int new_sock = accept(listen_sock,(struct sockaddr*)&peer,&len);
    if(new_sock < 0)
    {
      continue;
    }
    cout << "get a new link :new_sock is " << new_sock <<" ";
    uint16_t peer_port = ntohs(peer.sin_port);
    string peer_ip = inet_ntoa(peer.sin_addr);
    cout << "peer port is :" << peer_port << " peer_ip is " << peer_ip << endl;
     
    //创建线程提供服务,新线程进行了线程分离，所以主线程不需要等待新线程退出,可以继续获取连接
    pthread_t tid;
    int* sock = new int(new_sock);
    pthread_create(&tid,NULL,handle,(void*)sock);
  }
  return 0;
}
